package com.example.server.common.utils.sms;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.example.server.common.constant.RedisKey;
import com.example.server.common.constant.Result;
import com.example.server.common.constant.SMSConstants;
import com.example.server.common.constant.TokenConstants;
import com.example.server.common.service.aliyun.sms.DySmsApiSend;
import com.example.server.common.utils.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.Map;

/**
 * 短信
 */
@Slf4j
public class SMSUtil {

    private static RedisUtil redisUtil;

    @Resource
    private void getRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    //信息变更验证码
    private static final String TEMPLATE_CHANGE_INFO = "SMS_187620164";
    //用户注册验证码
    private static final String TEMPLATE_REGISTER_CUSTOMER = "SMS_187620166";
    //修改密码验证码
    private static final String TEMPLATE_RESET_PASSWORD = "SMS_187620165";

    private static SendSmsResponse send(String phone, String template_code, String tempParam) throws ClientException {
        return send(phone, template_code, tempParam, null);
    }

    private static SendSmsResponse send(String phone, String template_code) throws ClientException {
        return send(phone, template_code, null, null);
    }

    private static SendSmsResponse send(String phone, String template_code, Map<String, String> tempParam) throws ClientException {
        return send(phone, template_code, tempParam, null);
    }

    private static SendSmsResponse send(String phone, String template_code, Object tempParam, String outId) throws ClientException {
        String jsonStr = tempParam instanceof String ? (String) tempParam : JSONUtil.toJsonStr(tempParam);
        SendSmsResponse smsResponse = DySmsApiSend.sendSms(phone, template_code, jsonStr, outId);
        return smsResponse;
    }

    /**
     * 发送业务短信
     *
     * @param phone
     * @param bType
     * @return
     */
    public static Result sendMsgByBusiness(String phone, Integer bType) {
        return Result.OK();
    }

    /**
     * 发送短信验证码
     *
     * @param phone
     * @param codeType 验证码类型  0其他1注册2重置密码3修改手机号
     * @throws ClientException
     */
    public static Result sendCode(String phone, Integer codeType) throws ClientException {
        String code = RandomUtil.randomNumbers(4);
        StringBuilder str = new StringBuilder("{'code':'" + code + "'}");
        //修改重要信息
        String template = TEMPLATE_CHANGE_INFO;
        //注册用户
        if (SMSConstants.CodeType.REGISTER_CUSTOMER.getType() == codeType) {
            template = TEMPLATE_REGISTER_CUSTOMER;
        }
        //重置密码
        if (SMSConstants.CodeType.RESET_PASSWORD.getType() == codeType) {
            template = TEMPLATE_RESET_PASSWORD;
        }
        //修改手机号
        if (SMSConstants.CodeType.REGISTER_CUSTOMER.getType() == codeType) {
            template = TEMPLATE_CHANGE_INFO;
        }
        SendSmsResponse s = send(phone, template, str.toString());
        if (null != s && "OK".equals(s.getCode())) {
            redisUtil.set(RedisKey.SMS_CHECK + codeType + ":" + phone, code, 900);
            return Result.OK("发送成功");
        }
        log.error(JSONUtil.toJsonStr(s));
        return Result.Error("发送失败");
    }

    /**
     * 验证验证码
     *
     * @param phone
     * @param code
     * @return
     */
    public static int checkCode(String phone, String code, SMSConstants.CodeType codeType) {
        if (TokenConstants.DEV_MODEL) {
            return SMSConstants.CODE_CHECK_SUCCESS;
        }
        Object recode = redisUtil.get(RedisKey.SMS_CHECK + codeType.getType() + ":" + phone);
        if (recode == null) {
            //验证码已过期，或不存在
            return SMSConstants.CODE_CHECK_NOT_EXIST;
        }
        if (recode.equals(code)) {
            //重置密码的验证码在修改密码之后过期
            if (!SMSConstants.CodeType.RESET_PASSWORD.equals(codeType)) {
                redisUtil.deleteKey(RedisKey.SMS_CHECK + ":" + codeType.getType() + ":" + phone);
            }
            //校验通过
            return SMSConstants.CODE_CHECK_SUCCESS;
        }
        //验证码错误
        return SMSConstants.CODE_CHECK_FAILED;
    }

    public static void main(String[] args) throws ClientException {
        send("18428341939", TEMPLATE_REGISTER_CUSTOMER);
    }
}
